/*
 *	Yalala
 *	
 *	Copyright © MediaMonks B.V.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	1. Redistributions of source code must retain the above copyright
 *	   notice, this list of conditions and the following disclaimer.
 *	2. Redistributions in binary form must reproduce the above copyright
 *	   notice, this list of conditions and the following disclaimer in the
 *	   documentation and/or other materials provided with the distribution.
 *	3. All advertising materials mentioning features or use of this software
 *	   must display the following acknowledgement:
 *	   This product includes software developed by MediaMonks B.V.
 *	4. Neither the name of MediaMonks B.V. nor the
 *	   names of its contributors may be used to endorse or promote products
 *	   derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY MEDIAMONKS B.V. ''AS IS'' AND ANY
 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL MEDIAMONKS B.V. BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *	
 */

package com.mediamonks.yalala.ui.table 
{
	import temple.ui.scroll.ScrollPane;

	import com.mediamonks.yalala.data.vo.RowData;

	import flash.events.Event;
	import flash.geom.Rectangle;

	/**
	 * @author Thijs Broerse
	 */
	public class Table extends ScrollPane 
	{
		private static const _ROW_HEIGHT:Number = 14;

		private var _data:Vector.<RowData>;
		private var _rows:Vector.<Row>;
		private var _rowDataOffset:uint;
		private var _highLight:String;
		private var _contentWidth:Number;

		public function Table() 
		{
			_data = new Vector.<RowData>();
			_rows = new Vector.<Row>();
		}
		
		public function get data():Vector.<RowData>
		{
			return _data;
		}
		
		public function set data(value:Vector.<RowData>):void
		{
			_data = value;
			
			var i:int, len:uint, data:RowData, previous:RowData;
			
			for (i = 0, len = _data.length; i < len; i++)
			{
				data = _data[i];
				if (!previous)
				{
					data.highlighted = false;
				}
				else
				{
					data.highlighted = data.message.frame == previous.message.frame ? previous.highlighted : !previous.highlighted;
				}
				previous = data;
			}
			
			len = Math.ceil(height / _ROW_HEIGHT);
			len = Math.min(len, _data.length - _rowDataOffset);
			len = Math.max(len, _rows.length);
			
			for (i = 0; i < len; i++)
			{
				if (i >= _rows.length)
				{
					createRow();
				}
				if (i + _rowDataOffset < _data.length)
				{
					_rows[i].data = _data[i + _rowDataOffset];
					_rows[i].highLight(_highLight);
				}
				else
				{
					_rows[i].data = null;
				}
			}
			dispatchEvent(new Event(Event.RESIZE));
		}

		public function clear():void 
		{
			_data.length = 0;
			_rowDataOffset = 0;
			scrollV = scrollH = 0;
			for each (var row : Row in _rows)
			{
				row.data = null;
			}
			dispatchEvent(new Event(Event.RESIZE));
		}

		public function highLight(text:String):void 
		{
			_highLight = text;
			
			for (var i:int = 0, leni:int = _rows.length; i < leni; i++)
			{
				_rows[i].highLight(_highLight);
			}
		}

		override public function get contentWidth():Number 
		{
			if (isNaN(_contentWidth)) _contentWidth = 0; 
			
			if (super.contentWidth > _contentWidth)
			{
				_contentWidth = super.contentWidth;
			}
			return _contentWidth;
		}

		override public function get contentHeight():Number 
		{
			return _data.length * _ROW_HEIGHT;
		}

		override public function set scrollRect(value:Rectangle):void 
		{
			super.scrollRect = value;
			
			if (!_rows || !_rows.length || !value) return;
			
			var numRows:uint = height / _ROW_HEIGHT + 1;
			
			var i:uint;
			
			// check if we have enough rows
			while (_data.length > _rows.length && _rows.length < numRows)
			{
				createRow();
				i = _rows.length - 1;
				if (i + _rowDataOffset < _data.length)
				{
					_rows[i].data = _data[i + _rowDataOffset];
					_rows[i].highLight(_highLight);
				}
				else
				{
					_rows[i].data = null;
				}
			}
			
			// scroll down, move all rows above the top to the buttom of the list
			var row:Row = _rows[0];
			while (row.y < (value.y - _ROW_HEIGHT))
			{
				row.y += _rows.length * _ROW_HEIGHT;
				
				if (_rowDataOffset + _rows.length < _data.length)
				{
					row.data = _data[_rowDataOffset + _rows.length];
					row.highLight(_highLight);
				}
				else
				{
					row.data = null;
				}
				_rows.push(_rows.shift());
				row = _rows[0];
				_rowDataOffset++;
			}
			// scroll up, move rows at the bottom to the top (if needed)
			while (row.y > value.y)
			{
				row = _rows.pop();
				_rows.unshift(row);
				row.y -= _rows.length * _ROW_HEIGHT;
				if (_rowDataOffset)
				{
					row.data = _data[--_rowDataOffset];
					row.highLight(_highLight);
				}
				else
				{
					row.data = null;
				}
			}
		}

		private function createRow():void 
		{
			var row:Row = new Row();
			
			if (_rows.length)
			{
				row.y = _rows[_rows.length - 1].y + _ROW_HEIGHT;
			}
			addChild(row);
			_rows.push(row);
		}
	}
}
